package com.whisperarts.financer.app.widgets;

import java.math.BigDecimal;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.forms.widgets.FormToolkit;

public class AmountComposite extends Composite {
	
	private final IncomeButton button;
	
	private final Listener digits = new Listener ()	{
		@Override
		public void handleEvent (Event e) {
			String string = e.text;
			char [] chars = new char [string.length ()];
			string.getChars (0, chars.length, chars, 0);
			for (int i=0; i < chars.length; i++) {
				if (!('0' <= chars [i] && chars [i] <= '9')) {
					e.doit = false;
					return;
				}
			}
		}
	};
	
	private final MouseListener clicked = new MouseAdapter() {
		@Override
		public void mouseUp(MouseEvent e) {
			Text t = (Text)e.getSource();
			t.selectAll();
		};
	};

	private final Text textAmount, textAmountCent;

	private final Label symbolLabel;
	
	public AmountComposite(Composite parent, int style, String currencySymbol, boolean... isIncomeFlag) {
		super(parent, style);		
		
		FormToolkit toolkit = new FormToolkit(this.getDisplay());
		toolkit.adapt(this);
		GridLayout gridLayout = new GridLayout();
		gridLayout.numColumns = 5;
		gridLayout.makeColumnsEqualWidth = false;
		gridLayout.verticalSpacing = gridLayout.horizontalSpacing = 3;
		gridLayout.marginHeight = gridLayout.marginWidth = 3;
		setLayout(gridLayout);
		
		button = new IncomeButton(this, style);
		
		textAmount = toolkit.createText(this, "0", SWT.RIGHT | SWT.BORDER);
		textAmount.addListener (SWT.Verify, digits);
		textAmount.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		textAmount.setTextLimit(15);
//		textAmount.setLayoutData(new GridData(100, SWT.DEFAULT));
		textAmount.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		textAmount.addFocusListener(new FocusListener() {
			
			@Override
			public void focusLost(FocusEvent e) {
				if (textAmount.getText().length() == 0)
					textAmount.setText("0");
			}
			
			@Override
			public void focusGained(FocusEvent e) {
				textAmount.selectAll();
			}
		});
		textAmount.addMouseWheelListener(new MouseWheelListener() {
			@Override
			public void mouseScrolled(MouseEvent e) {
				if (!textAmount.isFocusControl()) 
					return;
				handleAmount(e.count > 0, "5");
			}
		});
		textAmount.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
				if (e.keyCode == SWT.ARROW_UP) {
					handleAmount(true, "1");
				} else if (e.keyCode == SWT.ARROW_DOWN) {
					handleAmount(false, "1");
				} else {				
					super.keyPressed(e);
				}
			}
		});
		textAmount.addMouseListener(clicked);
		
		toolkit.createLabel(this, ".");
		
		textAmountCent = toolkit.createText(this, "00", SWT.BORDER);
		textAmountCent.addListener (SWT.Verify, digits);
		textAmountCent.setTextLimit(2);
		textAmountCent.addFocusListener(new FocusListener() {
			@Override
			public void focusLost(FocusEvent e) {
				if (textAmountCent.getText().length() == 0)
					textAmountCent.setText("00");
				else if (textAmountCent.getText().length() == 1) {
					String cents = "0" + textAmountCent.getText();
					textAmountCent.setText(cents);
				}
			}
			
			@Override
			public void focusGained(FocusEvent e) {
				textAmountCent.selectAll();
			}
		});
		textAmountCent.addMouseWheelListener(new MouseWheelListener() {
			@Override
			public void mouseScrolled(MouseEvent e) {
				if (!textAmountCent.isFocusControl())
					return;
				
				handleAmountCent(e.count > 0, 5);
			}
		});
		textAmountCent.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
				if (e.keyCode == SWT.ARROW_UP) {
					handleAmountCent(true, 1);
				} else if (e.keyCode == SWT.ARROW_DOWN) {
					handleAmountCent(false, 1);
				} else {				
					super.keyPressed(e);
				}
			}
		});
		textAmountCent.addMouseListener(clicked);
		
		symbolLabel = toolkit.createLabel(this, currencySymbol);
		
		if (isIncomeFlag.length != 0) {
			setIncome(true);
		}

	}
	
	private void handleAmount(boolean increase, String amountToChange) {
		BigDecimal amount = new BigDecimal(textAmount.getText());
		String result = amount.toString();
		if (increase) {
			result = amount.add(new BigDecimal(amountToChange)).toString();
		} else if (amount.compareTo(new BigDecimal(amountToChange)) >= 0) {
			result = amount.subtract(new BigDecimal(amountToChange)).toString();					
		}
		textAmount.setText(result);
		textAmount.selectAll();
	}
	
	private void handleAmountCent(boolean increase, int amountToChange) {
		BigDecimal amount = new BigDecimal(textAmountCent.getText());
		String result = amount.toString();
		if (increase) {
			if (amount.compareTo(new BigDecimal("" + (100-amountToChange))) >= 0) 
				return;
			
			result = amount.add(new BigDecimal("" + amountToChange)).toString();
		} else if (amount.compareTo(new BigDecimal("" + amountToChange)) >= 0) {
			result = amount.subtract(new BigDecimal("" + amountToChange)).toString();					
		}
		if (result.length() == 1) {
			result = "0" + result;
		}
		textAmountCent.setText(result);
		textAmountCent.selectAll();
	}
	
	public boolean isIncome() {
		return button.isIncome();
	}

	public void setIncome(boolean income) {
		button.setIncome(income);
	}

	public BigDecimal getAmount() {
		return new BigDecimal(textAmount.getText() + "." + textAmountCent.getText());
	}

	public void setAmount(BigDecimal amount) {		
		String[] split = amount.toString().split("\\.");
		textAmount.setText(split[0]); 
		if (split.length > 1) {
			String cents = split[1];
			if (cents.length() == 1)
				cents = "0" + cents;
			textAmountCent.setText(cents);
		}
	}
	
	@Override
	public boolean setFocus() {
		return textAmount.setFocus();
	}
	
	public void setSymbolLabel(String symbol) {
		symbolLabel.setText(symbol);
	}
}
